# include <bits/stdc++.h>
# define mid ((l + r) >> 1)
# define MAXN 10023
# define MAXM 50023
using namespace std;

inline int gn() {
	int k = 0, f = 1;
	char c = getchar();
	for(; !isdigit(c); c = getchar()) if(c == '-') f = -1;
	for(; isdigit(c); c = getchar()) k = k * 10 + c - '0';
	return k * f;
}

struct ed {
	int fr, to, w, ne;
	inline ed() {;}
	inline ed(int fr_, int to_, int w_, int ne_) {
		fr = fr_, ne = ne_, w = w_, to = to_;
	}
}e[MAXM];

inline bool cmp(ed a, ed b) {
	return a.w > b.w;
}

int hed[MAXN], ct;


inline void addedge(int fr, int to, int w) {
	e[++ct] = ed(fr, to, w, hed[fr]), hed[fr] = ct;
}

struct edge {
	int to, w;
	edge *ne;
	inline edge() {
		to = w = 0;
		ne = NULL;
	}
	inline edge(int to_, int w_, edge *ne_) {
		to = to_, w = w_, ne = ne_;
	}
}*head[MAXN];

inline void add_edge(int fr ,int to, int w) {
	edge *x = new edge(to, w, head[fr]);
	head[fr] = x;
	edge *y = new edge(fr, w, head[to]);
	head[to] = y;
}

int n, m, intree[MAXN], cnt;

int u[MAXN];

int get_fa(int x) {
	if(x == u[x]) return x;
	else return u[x] = get_fa(u[x]);
}

inline void merge(int x, int y) {
	x = get_fa(x), y = get_fa(y);
	u[y] = x;
}

inline void kruscal() {
	for(int i = 1;i <= n; i++) u[i] = i;
	sort(e + 1, e + m + 1, cmp);
	for(int i = 1; i <= m; i++) {
		int x = e[i].fr, y = e[i].to;
		if(get_fa(x) == get_fa(y)) continue;
		add_edge(x, y, e[i].w);
		merge(x, y);
	}
}

int dep[MAXN], fa[MAXN], siz[MAXN], que[MAXN], son[MAXN], a[MAXN];
bool vis[MAXN];

inline void bfs(int s) {
	memset(que, 0, sizeof(que));
	int l = 1, r = 1;
	que[1] = s;
	while(l <= r) {
		int u = que[l++];
		vis[u] = 1;
		siz[u] = 1, dep[u] = dep[fa[u]] + 1;
		for(edge *e = head[u]; e; e = e->ne) {
			if(e->to != fa[u]) a[e->to] = e->w, fa[e->to] = u, que[++r] = e->to;
		}
	}
	for(int i = r; i; i--) {
		siz[fa[que[i]]] += siz[que[i]];
		if(siz[que[i]] > siz[son[fa[que[i]]]]) son[fa[que[i]]] = que[i];
	}
}

int dfn[MAXN], adfn[MAXN], ids, top[MAXN];

void dfs(int x, int tp) {
	top[x] = tp;
	dfn[x] = ++ids;
	adfn[ids] = ids;
	if(!son[x]) return;
	dfs(son[x], tp);
	for(edge *e = head[x]; e; e = e->ne) {
		if(dfn[e->to]) continue;
		dfs(e->to, e->to);
	}
}

struct node {
	int mx, mi;
	node *ls, *rs;
	inline node() {
		ls = rs = NULL;
		mx = 0;
		mi = 0x7fffffff;
	}
	inline node(int x) {
		mi = mx = x;
	}
	inline node(node *ls_, node *rs_) {
		ls = ls_, rs = rs_;
	}
	inline void push_up() {
		mx = max(ls->mx, rs->mx);
		mi = min(ls->mi, rs->mi);
	}
}*root;

node *build(int l, int r) {
	if(l == r) {
		node *x = new node(a[l]);
		return x;
	} else {
		node *x = new node(build(l, mid), build(mid + 1, r));
		x->push_up();
		return x;
	} 
}

int main() {
	freopen("in.txt", "r", stdin);
	n = gn();
	m = gn();
	for(int i = 1; i <= m; i++) {
		int a = gn();
		int b = gn();
		addedge(a, b, gn());
	}
	kruscal();
	memset(son, -1, sizeof(son));
	for(int i = 1; i <= n; i++) {
		if(vis[i]) continue;
		bfs(i);
		dfs(i, i);
	}
	root = build(1, n);

}
